package com.xteam.xnetworkdisk.sys.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xteam.xnetworkdisk.common.CurrentUser;
import com.xteam.xnetworkdisk.config.MinioConfigOld;
import com.xteam.xnetworkdisk.constant.Constant;
import com.xteam.xnetworkdisk.sys.dao.FileDao;
import com.xteam.xnetworkdisk.sys.dao.FileShareRelationDao;
import com.xteam.xnetworkdisk.sys.dao.ShareDao;
import com.xteam.xnetworkdisk.sys.dao.UserDao;
import com.xteam.xnetworkdisk.sys.entity.FileEntity;
import com.xteam.xnetworkdisk.sys.entity.FileShareRelationEntity;
import com.xteam.xnetworkdisk.sys.entity.ShareEntity;
import com.xteam.xnetworkdisk.sys.entity.UserEntity;
import com.xteam.xnetworkdisk.sys.service.ShareService;
import com.xteam.xnetworkdisk.utils.FileLocalUtils;
import com.xteam.xnetworkdisk.utils.MinioUtilsNew;
import com.xteam.xnetworkdisk.utils.MinioUtilsOld;
import com.xteam.xnetworkdisk.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.*;

@Service("share")
public class ShareServiceImpl extends ServiceImpl<ShareDao,ShareEntity> implements ShareService {

    @Resource
    private ShareDao shareDao;

    @Resource
    private FileShareRelationDao fileShareRelationDao;

    @Resource
    private FileDao fileDao;

    @Resource
    private UserDao userDao;

//    @Resource
//    private MinioUtilsNew minioUtils;
    @Autowired
    private FileLocalUtils fileLocalUtils;

    @Override
    @Transactional
    public Integer shareFileById(List<Integer> fileIds,String shareName) {
        // 生成分享数据
        ShareEntity shareEntity =  new ShareEntity();
        shareEntity.setUserId(CurrentUser.getCurrentUserId());
        //shareEntity.setUserId(1785409564);
        shareEntity.setShareName(shareName);
        shareEntity.setCreateTime(new Date(System.currentTimeMillis()));
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(shareEntity.getCreateTime());
        calendar.add(Calendar.DAY_OF_MONTH,Constant.SHARE_DEFAULT_EXPIRE_TIME);
        Date over = calendar.getTime();
        shareEntity.setOverTime(over);
        shareDao.insertShare(shareEntity);
        Integer shareId = shareEntity.getShareId();
        // 生成分享数据与文件的关联关系
        List<FileShareRelationEntity> fileShareRelationEntityList = new ArrayList<>();
        for (Integer fileId : fileIds) {
            fileShareRelationEntityList.add(new FileShareRelationEntity(null,shareId,fileId));
        }
        fileShareRelationDao.batchInsert(fileShareRelationEntityList);
        return shareId;
    }

    @Override
    public R getSharedFiles(String shareId) {
        // 解码得到真正的shareId
        byte[] decode = Base64.getDecoder().decode(shareId);
        String tempShareId = new String(decode, StandardCharsets.UTF_8);
        Integer trueShareId = Integer.parseInt(tempShareId);
        if(shareDao.selectById(trueShareId) == null ||
                shareDao.selectById(trueShareId).getOverTime().before(new Date(System.currentTimeMillis()))){
            return R.error("链接已失效");
        }
        List<FileShareRelationEntity> fileList = fileShareRelationDao.selectList(new LambdaQueryWrapper<FileShareRelationEntity>().eq(FileShareRelationEntity::getShareId, trueShareId));
        if(ArrayUtil.isEmpty(fileList)) {
            return R.error("来晚了，文件不见了");
        }
        //UserEntity userEntity = userDao.selectById(1785409564);

        List<Integer> fileIds = fileList.stream().map(FileShareRelationEntity::getFileId).toList();
        List<FileEntity> fileEntities = fileDao.selectBatchIds(fileIds).stream().filter(FileEntity::getIsValid).toList();
        return R.ok(Map.of("username",userDao.selectById(fileEntities.get(0).getUserId()).getName(),"files",fileEntities));
    }

    @Override
    @Transactional
    public void cancelShared(List<Integer> shareIds) {
        shareDao.setShareExpireByIds(shareIds);
    }

    @Override
    public R getMyShared() {
        List<ShareEntity> shareEntities = shareDao.selectByMap(Map.of("user_id", CurrentUser.getCurrentUserId()));
        // 过期后返回null
        shareEntities.forEach(shareEntity -> {
            if(shareEntity.getOverTime().before(new Date(System.currentTimeMillis()))) {
                shareEntity.setOverTime(null);
            }
        });
        //    List<ShareEntity> shareEntities = shareDao.selectByMap(Map.of("user_id", 1785409564));
        //List<Integer> shareIds = shareEntities.stream().map(ShareEntity::getShareId).toList();
        return R.ok().put("share",shareEntities);
//        if(shareIds.isEmpty()) {
//            return R.ok().put("share",null);
//        }
//        List<FileShareRelationEntity> fileShareRelationEntityList = fileShareRelationDao.selectList(new LambdaQueryWrapper<FileShareRelationEntity>().in(FileShareRelationEntity::getShareId, shareIds));
//        List<Integer> fileIds = fileShareRelationEntityList.stream().map(FileShareRelationEntity::getFileId).toList();
//        List<FileEntity> fileEntities = fileDao.selectBatchIds(fileIds).stream().filter(FileEntity::getIsValid).toList();
//        return R.ok().put("files",fileEntities);
    }

    @Override
    @Transactional
    public R saveTo(List<Integer> fileIds,Integer folderId) throws RuntimeException {
        // 获取文件列表,计算空间
        List<FileEntity> fileEntities = fileDao.selectBatchIds(fileIds);
        long totalSize = fileEntities.stream().map(FileEntity::getFileSize).reduce(0L, Long::sum);
        UserEntity userEntity = userDao.selectById(CurrentUser.getCurrentUserId());
        if(userEntity.getUseSpace()+totalSize>userEntity.getTotalSpace()) {
            return R.error(Constant.USER_SPACE_OVER);
        }
        for (FileEntity fileEntity : fileEntities) {
            //URL url = new URL(fileEntity.getFilePath());
            //HttpURLConnection httpsURLConnection = (HttpURLConnection) url.openConnection();
            //BufferedInputStream inputStream = new BufferedInputStream(httpsURLConnection.getInputStream());
            //String suffix = fileEntity.getFileName().substring(fileEntity.getFileName().lastIndexOf("."));
            //String copyFileName = System.currentTimeMillis() + fileEntity.getFileName().substring(fileEntity.getFileName().lastIndexOf("."));

            // 在Minio重新复制一份
            String filePath = fileEntity.getFilePath();
            String fileNameInBuket = filePath.substring(filePath.lastIndexOf('/'));
            String copyPath = fileLocalUtils.copyFile(Constant.USER_FILE_BUKET,fileNameInBuket);

            // 检查当前文件夹是否有重复的文件名
            FileEntity existedFile = fileDao.selectOne(new LambdaQueryWrapper<FileEntity>()
                    .eq(FileEntity::getFolderId, folderId)
                    .eq(FileEntity::getFileName, fileEntity.getFileName()));

            if(existedFile != null) {
                return R.error(Constant.FILE_ALREADY_EXISTED);
            }

            // 构造新的文件实体对象
            fileEntity.setFolderId(folderId);
            fileEntity.setUserId(CurrentUser.getCurrentUserId());
            fileEntity.setCreatedAt(new Date());
            fileEntity.setUpdatedAt(new Date());
            fileEntity.setFileId(null);
            fileEntity.setFilePath(copyPath);
            fileDao.insertFile(fileEntity);
        }
        return R.ok("文件保存成功");
    }

    @Override
    public void deleteShare(List<Integer> shareIds) {
        shareDao.deleteBatchIds(shareIds);
        fileShareRelationDao.delete(new LambdaQueryWrapper<FileShareRelationEntity>().in(FileShareRelationEntity::getShareId, shareIds));
    }
}
